package cz.vse.integrace.iag.db;

import com.google.gdata.data.Link;
import com.google.gdata.data.contacts.ContactEntry;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Transient;

/**
 * Třída představující zaměstnace, který je ukládán do databáze.
 * 
 * @author David Nejedly
 * @version 1.0
 */
@Entity
public class Zamestnanec implements Serializable {

    @Id
    @GeneratedValue
    private Integer id;
    @ManyToOne(fetch = FetchType.EAGER)
    private Oddeleni oddeleni;
    private String jmeno;
    private String prijmeni;
    private String emailPrace;
    private String heslo;
    private double hrubaMzda;
    private String pozice;
    private byte[] fotka;
    private String accessToken;
    private Long expiresIn;
    private String refreshToken;
    private String scope;
    @OneToOne(cascade= CascadeType.ALL)
    private Adresa prace;
    @OneToOne(cascade= CascadeType.ALL)
    private Adresa doma;
    private String emailDoma;
    private String kontaktId;
    @Transient
    private ContactEntry kontakt;
    @Transient
    private List<ContactEntry> kontakty;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 
     * @return email domů
     */
    public String getEmailDoma() {
        return emailDoma;
    }

    /**
     * 
     * @param emailDoma 
     */
    public void setEmailDoma(String emailDoma) {
        this.emailDoma = emailDoma;
    }

    /**
     * 
     * @return pracovní email, podle něj se synchornizuje
     */
    public String getEmailPrace() {
        return emailPrace;
    }

    /**
     * 
     * @param emailPrace pracovní email, podle něj se synchornizuje
     */
    public void setEmailPrace(String emailPrace) {
        this.emailPrace = emailPrace;
    }

    /**
     * 
     * @return byty fotografie zaměstnance
     */
    public byte[] getFotka() {
        return fotka;
    }

    /**
     * 
     * @param fotka byty fotografie zaměstnance
     */
    public void setFotka(byte[] fotka) {
        this.fotka = fotka;
    }

    /**
     * 
     * @return heslo k pracovnímu emailu
     */
    public String getHeslo() {
        return heslo;
    }

    /**
     * 
     * @param heslo heslo k pracovnímu emailu
     */
    public void setHeslo(String heslo) {
        this.heslo = heslo;
    }

    /**
     * 
     * @return hrubá mzda zaměstnance
     */
    public double getHrubaMzda() {
        return hrubaMzda;
    }

    /**
     * 
     * @param hrubaMzda hrubá mzda zaměstnance
     */
    public void setHrubaMzda(double hrubaMzda) {
        this.hrubaMzda = hrubaMzda;
    }

    /**
     * 
     * @return jméno
     */
    public String getJmeno() {
        return jmeno;
    }

    /**
     * 
     * @param jmeno 
     */
    public void setJmeno(String jmeno) {
        this.jmeno = jmeno;
    }

    /**
     * 
     * @return oddělení ve kterém je zaměstnanec zaměstnán
     */
    public Oddeleni getOddeleni() {
        return oddeleni;
    }

    /**
     * 
     * @param oddeleni oddělení ve kterém je zaměstnanec zaměstnán
     */
    public void setOddeleni(Oddeleni oddeleni) {
        this.oddeleni = oddeleni;
    }

    /**
     * 
     * @return příjmení
     */
    public String getPrijmeni() {
        return prijmeni;
    }

    /**
     * 
     * @param prijmeni 
     */
    public void setPrijmeni(String prijmeni) {
        this.prijmeni = prijmeni;
    }

    /**
     * 
     * @return přístupový token k google api
     */
    public String getAccessToken() {
        return accessToken;
    }

    /**
     * 
     * @param accessToken přístupový token k google api
     */
    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    /**
     * 
     * @return čas v sekundách za jak dlouho vyprší přístupový token
     */
    public Long getExpiresIn() {
        return expiresIn;
    }

    /**
     * 
     * @param expiresIn čas v sekundách za jak dlouho vyprší přístupový token
     */
    public void setExpiresIn(Long expiresIn) {
        this.expiresIn = expiresIn;
    }

    /**
     * 
     * @return pozice na které za zaměstnán
     */
    public String getPozice() {
        return pozice;
    }

    /**
     * 
     * @param pozice pozice na které za zaměstnán
     */
    public void setPozice(String pozice) {
        this.pozice = pozice;
    }

    /**
     * 
     * @return obnovovací token pro přístup k google api
     */
    public String getRefreshToken() {
        return refreshToken;
    }

    /**
     * 
     * @param refreshToken obnovovací token pro přístup k google api
     */
    public void setRefreshToken(String refreshToken) {
        this.refreshToken = refreshToken;
    }

    /**
     * 
     * @return scope pro který je platný token
     */
    public String getScope() {
        return scope;
    }

    /**
     * 
     * @param scope scope pro který je platný token
     */
    public void setScope(String scope) {
        this.scope = scope;
    }

    /**
     * 
     * @return jméno příjmení
     */
    public String getCeleJmeno() {
        return jmeno + " " + prijmeni;
    }

    /**
     * 
     * @return google kontakt zaměstnance
     */
    public ContactEntry getKontakt() {
        return kontakt;
    }

    /**
     * 
     * @param kontakt google kontakt zaměstnance
     */
    public void setKontakt(ContactEntry kontakt) {
        this.kontakt = kontakt;
    }

    /**
     * 
     * @return id kontaktu zaměstnance
     */
    public String getKontaktId() {
        return kontaktId;
    }

    /**
     * 
     * @param kontaktId id google kontaktu zaměstnance
     */
    public void setKontaktId(String kontaktId) {
        this.kontaktId = kontaktId;
    }

    /**
     * 
     * @return adresa domů
     */
    public Adresa getDoma() {
        return doma;
    }

    /**
     * 
     * @param doma adresa domů
     */
    public void setDoma(Adresa doma) {
        this.doma = doma;
    }

    /**
     * 
     * @return adresa do práce
     */
    public Adresa getPrace() {
        return prace;
    }

    /**
     * 
     * @param prace adresa do práce
     */
    public void setPrace(Adresa prace) {
        this.prace = prace;
    }

    /**
     * 
     * @return google kontakty zaměstnance
     */
    public List<ContactEntry> getKontakty() {
        return kontakty;
    }

    /**
     * 
     * @param kontakty google kontakty zaměstnance
     */
    public void setKontakty(List<ContactEntry> kontakty) {
        this.kontakty = kontakty;
    }

    /**
     * 
     * @param obj jiný objekt
     * @return true pokud mají oba zaměstnaci stejný pracovní email
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Zamestnanec other = (Zamestnanec) obj;
        if ((this.emailPrace == null) ? (other.emailPrace != null) : !this.emailPrace.equals(other.emailPrace)) {
            return false;
        }
        return true;
    }

    /**
     * 
     * @return hash na základě pracovního emailu
     */
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 13 * hash + (this.emailPrace != null ? this.emailPrace.hashCode() : 0);
        return hash;
    }

    /**
     * Metodaá přidává google kontakt do seznamu kontaktů. 
     * Pokud je nalezen kontakt se stejným celým jménem, tak je nahazen 
     * přidávaným kontaktem.
     * 
     * @param kontakt kontakt k přidání
     */
    public void addKontakt(ContactEntry kontakt) {
        if (kontakty == null) {
            kontakty = new ArrayList<ContactEntry>();
        }
        boolean stejnyKontakt = false;
        for (ContactEntry kont : kontakty) {
            if (kont != null && kont.hasName() && kont.getName().hasFullName() && kont.getName().getFullName().hasValue()
                    && kontakt != null && kontakt.hasName() && kont.getName().hasFullName() && kont.getName().getFullName().hasValue()
                    && kontakt.getName().getFullName().getValue().equals(kont.getName().getFullName().getValue())) {
                kontakt.removeLinks();
                for (Link link : kont.getLinks()) {
                    kontakt.addLink(link);
                }
                kontakt.setEtag(kont.getEtag());
                kontakt.setVersionId(kont.getVersionId());
                kontakt.setId(kont.getId());
                kont = kontakt;
                stejnyKontakt = true;
            }
        }
        if (!stejnyKontakt) {
            kontakty.add(kontakt);
        }
    }
}
